﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using StockUtil;

namespace StockLib.Data
{
    public class XdrFileSaver
    {
        public virtual void Save(Stock stock, List<XdrData> xdrData)
        {
            FileInfo fi = new FileInfo(StockData.Instance.GetFileName(stock, DataType.XDR));
            FileStream fs = null;

            try
            {
                if (!fi.Directory.Exists)
                    Directory.CreateDirectory(fi.Directory.FullName);

                fs = new FileStream(fi.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                foreach (XdrData data in xdrData)
                {
                    XdrFilePack pack = XdrFilePack.FromInternal(data);
                    byte[] buffer = StructHelper.ToBytes(pack);

                    bool hasPack = false;
                    bool insertPack = false;
                    byte[] bufferOld = new byte[Marshal.SizeOf(typeof(XdrFilePack))];
                    while (fs.Read(bufferOld, 0, bufferOld.Length) > 0)
                    {
                        XdrFilePack packOld = (XdrFilePack)StructHelper.FromBytes(bufferOld, typeof(XdrFilePack));

                        if (pack.m_time == packOld.m_time)
                        {
                            hasPack = true;
                            fs.Seek(fs.Position - bufferOld.Length, SeekOrigin.Begin);
                            break;
                        }

                        if (pack.m_time < packOld.m_time)
                        {
                            insertPack = true;
                            break;
                        }
                    }

                    if (hasPack || !insertPack)
                    {
                        fs.Write(buffer, 0, buffer.Length);
                    }
                    else if (insertPack)
                    {
                        int flen = (int)fs.Length;
                        int fpos = (int)fs.Position;
                        byte[] bufferTemp = new byte[flen - fpos + 1];
                        if (bufferTemp != null)
                        {
                            if (flen - fpos > 0)
                                fs.Read(bufferTemp, 0, flen - fpos);

                            fs.Seek(fpos - bufferOld.Length, SeekOrigin.Begin);
                            fs.Write(buffer, 0, buffer.Length);
                            fs.Write(bufferOld, 0, bufferOld.Length);
                            if (flen - fpos > 0)
                                fs.Write(bufferTemp, 0, flen - fpos);
                            bufferTemp = null;
                        }
                        fs.Seek(fpos, SeekOrigin.Begin);
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
                throw ex;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
        }
    }
}
